﻿#region Copyright ©2008-2011, Technische Universitaet Muenchen
// ====================================================================================================
//
// Last Changed by       $Author: then $
// Last Changed Date     $LastChangedDate: 2009-06-16 17:17:03 +0200 (Tue, 16 Jun 2009) $
// Last Changed Revision $Rev: 209 $
//
// ====================================================================================================
#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Resources;
using System.Text.RegularExpressions;

namespace Tum.CollabXT.TFS
{
    static class Helper
    {
        private static Regex RemoveInvalidTFSCharsRegEx = new Regex(@"([/,\\,?,$,*,:,"",&,>,<,#,%,|,\[,\]])*", RegexOptions.Compiled);
        private static Regex RemoveMultipleWhitespaceRegEx = new Regex(@"(\ )+", RegexOptions.Compiled);

        public const int TFS_MaxWorkItemTitleLen = 128;
        public const int TFS_MaxWorkItemTextLen = 255;

        public static readonly char[] FolderSeperators = new char[] { '\\', '/' };


        /// <summary>
        /// Copies a whole directory and all of its files (recursively)
        /// </summary>
        public static void CopyDirectory(string src, string dest)
        {
            if (!src.EndsWith("/", StringComparison.OrdinalIgnoreCase) && !src.EndsWith("\\", StringComparison.OrdinalIgnoreCase))
                src += "/";
            if (!dest.EndsWith("/", StringComparison.OrdinalIgnoreCase) && !dest.EndsWith("\\", StringComparison.OrdinalIgnoreCase))
                dest += "/";

            Directory.CreateDirectory(dest);

            foreach (string curFileName in Directory.GetFiles(src))
            {
                var destPath = dest + FileNameFromPath(curFileName);
                try
                {
                    File.Copy(curFileName, dest + FileNameFromPath(curFileName), true);
                }
                catch (IOException e)
                {
                    throw new FileCopyException(curFileName, destPath, e);
                }
            }

            foreach (string curDirectory in Directory.GetDirectories(src))
                CopyDirectory(curDirectory, dest + LastDirectoryFromPath(curDirectory));
        }

        /// <summary>
        /// Deletes a directory not regarding read-only files.
        /// </summary>
        /// <param name="dir">Directory to be deleted.</param>
        public static void DeleteDirectory(string dir)
        {
            string[] subdirs = Directory.GetDirectories(dir);
            foreach (string curDir in subdirs)
                DeleteDirectory(curDir);

            string[] files = Directory.GetFiles(dir);
            foreach (string curFile in files)
            {
                try
                {
                    File.SetAttributes(curFile, FileAttributes.Normal);
                    File.Delete(curFile);
                }
                catch(Exception) { }
            }

            try
            {
                Directory.Delete(dir);
            }
            catch(Exception) { }
        }

        /// <summary>
        /// Returns the file name from a path
        /// </summary>
        public static string FileNameFromPath(string path)
        {
            return path.Substring(Math.Max(path.LastIndexOf('/'), path.LastIndexOf('\\')) + 1);
        }

        /// <summary>
        /// Returns the directory name at the deepest level from a path
        /// </summary>
        public static string LastDirectoryFromPath(string path)
        {
            if (path.EndsWith("/", StringComparison.OrdinalIgnoreCase) || path.EndsWith("\\", StringComparison.OrdinalIgnoreCase))
                path = path.Substring(0, path.Length - 1);
            return path.Substring(path.LastIndexOfAny(FolderSeperators) + 1);
        }

        /// <summary>
        /// Prepares a string to be used in TFS files - strips it to a specific length and deletes reserved characters.
        /// </summary>
        /// <param name="str">String to be prepared</param>
        /// <param name="len">Maximal field length</param>
        /// <returns>Prepared string</returns>
        public static string PrepareStringForTFS(string str, int len)
        {
            str = str.Trim(); //No leading and trailing whitespace allowed
            str = RemoveMultipleWhitespaceRegEx.Replace(str, " "); //Remove multiple whitespaces
            str = str.Replace(Environment.NewLine, "<br/>"); //Special treatment for linebreaks

            bool moreTextAvail = str.Length > len;

            string shortenedStr = str;
            if (moreTextAvail)
                shortenedStr = str.Substring(0, len - 3);
            shortenedStr = RemoveInvalidTFSCharsRegEx.Replace(shortenedStr, "");

            if (moreTextAvail)
                shortenedStr += "...";
            return shortenedStr;
        }
    }
}
